home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Milan_1991 / Devcon91.2 / Bullet / spiral.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-01  |  9.6 KB  |  367 lines

  1. #ifdef   DEBUG
  2. #define  D(a)    kprintf(a)
  3. #else
  4. #define  D(a)
  5. #endif
  6. #include <exec/types.h>
  7. #include <dos/rdargs.h>
  8. #include <graphics/rastport.h>
  9. #include <intuition/intuition.h>
  10. #include "libraries/diskfonttag.h"
  11. #include "libraries/glyph.h"
  12.  
  13. #include <clib/exec_protos.h>
  14. #include <clib/dos_protos.h>
  15. #include <clib/graphics_protos.h>
  16. #include <clib/intuition_protos.h>
  17. #include <clib/utility_protos.h>
  18. #include "clib/bullet_protos.h"
  19. #include <pragmas/exec_pragmas.h>
  20. #include <pragmas/dos_pragmas.h>
  21. #include <pragmas/graphics_pragmas.h>
  22. #include <pragmas/intuition_pragmas.h>
  23. #include <pragmas/utility_pragmas.h>
  24. #include "pragmas/bullet_pragmas.h"
  25.  
  26. #include <math.h>
  27. #include <string.h>
  28. #undef    strchr
  29. #undef    strcmp
  30. #undef    strcpy
  31. #undef    strrchr
  32. #undef    memset
  33.  
  34. extern struct Library *SysBase;
  35. extern struct Library *DOSBase;
  36.  
  37. #define  TEMPLATE    "NAME,DPIX/N,DPIY/N,DOTPX/N,DOTPY/N"
  38.  
  39. #define  O_NAME        0
  40. #define  O_DPIX        1
  41. #define  O_DPIY        2
  42. #define  O_DOTPX    3
  43. #define  O_DOTPY    4
  44. #define  O_COUNT    5
  45.  
  46. #define  U_DPI        0
  47. #define  U_DOTP        1
  48. #define  U_COUNT    2
  49.  
  50. #define  MAXFILESIZE    4000
  51.  
  52. struct Library *GfxBase = 0;
  53. struct Library *IntuitionBase = 0;
  54. struct Library *UtilityBase = 0;
  55. struct RDArgs *RDArgs = 0;
  56. BPTR OTFile = 0;
  57. struct Library *BulletBase = 0;
  58. struct GlyphEngine *GlyphEngine = 0;
  59. struct TagItem OTags[MAXFILESIZE/sizeof(struct TagItem)];
  60. struct TagItem UTags[U_COUNT+1] = {
  61.     { OT_DeviceDPI, 0x00480048 },
  62.     { OT_DotSize, 0x00640064 },
  63.     { TAG_DONE, 0 }
  64. };
  65.  
  66. #define  X2    640
  67. #define  Y2    400
  68. #define  CX    (X2/2)
  69. #define  CY    (Y2/2)
  70. struct Window *Window = 0;
  71. struct IntuiMessage *IM;
  72. PLANEPTR Template = 0;
  73.  
  74. char SpiralText[] =    "This is a test of the Bullet library.  "
  75.             "The test is called \"Spiral\", for obvious reasons.";
  76.  
  77. void
  78. endGame(format, arg1, arg2, arg3, arg4)
  79. char *format, *arg1, *arg2, *arg3, *arg4;
  80. {
  81.     if (format)
  82.     printf(format, arg1, arg2, arg3, arg4);
  83.     if (Template)
  84.     FreeRaster(Template, X2, Y2);
  85.     if (Window)
  86.     CloseWindow(Window);
  87.     if (GlyphEngine)
  88.     CloseEngine(GlyphEngine);
  89.     if (BulletBase)
  90.     CloseLibrary(BulletBase);
  91.     if (OTFile)
  92.     Close(OTFile);
  93.     if (RDArgs)
  94.     FreeArgs(RDArgs);
  95.     if (UtilityBase)
  96.     CloseLibrary(UtilityBase);
  97.     if (IntuitionBase)
  98.     CloseLibrary(IntuitionBase);
  99.     if (GfxBase)
  100.     CloseLibrary(GfxBase);
  101.     if (format)
  102.     exit(5);
  103.     exit(0);
  104. }
  105.  
  106.  
  107. struct Window *
  108. myOpenWindowTags(tag)
  109. LONG tag;
  110. {
  111.     return(OpenWindowTagList(0, (struct TagItem *) &tag));
  112. }
  113.  
  114.  
  115. ULONG
  116. setInfo(ge, tag)
  117. struct GlyphEngine *ge;
  118. LONG tag;
  119. {
  120.     return(SetInfoA(ge, (struct TagItem *) &tag));
  121. }
  122.  
  123. ULONG
  124. obtainInfo(ge, tag)
  125. struct GlyphEngine *ge;
  126. LONG tag;
  127. {
  128.     return(ObtainInfoA(ge, (struct TagItem *) &tag));
  129. }
  130.  
  131. ULONG
  132. releaseInfo(ge, tag)
  133. struct GlyphEngine *ge;
  134. LONG tag;
  135. {
  136.     return(ReleaseInfoA(ge, (struct TagItem *) &tag));
  137. }
  138.  
  139. void
  140. main()
  141. {
  142.     struct GlyphMap *glyph;
  143.     ULONG error, *options[O_COUNT], result;
  144.     double h;
  145.     int i, x, y, points;
  146.     short charIndex, dx, dy;
  147.     LONG pointVal, sinVal, cosVal, escapement;
  148.     char pathStore[256], *filePath, *s;
  149.  
  150.     D(("Test\nOpenLibrarys..."));
  151.     GfxBase = OpenLibrary("graphics.library", 0);
  152.     if (!GfxBase)
  153.     endGame("ERROR: cannot open \"graphics.library\"\n");
  154.     IntuitionBase = OpenLibrary("intuition.library", 0);
  155.     if (!IntuitionBase)
  156.     endGame("ERROR: cannot open \"intuition.library\"\n");
  157.     UtilityBase = OpenLibrary("utility.library", 0);
  158.     if (!UtilityBase)
  159.     endGame("ERROR: cannot open \"utility.library\"\n");
  160.  
  161.     D(("ReadArgs..."));
  162.     memset(options, 0, sizeof(options));
  163.     RDArgs = ReadArgs(TEMPLATE, (LONG *) options, 0);
  164.     if (!RDArgs)
  165.     endGame("ERROR: invalid arguments\n");
  166.  
  167.     D((" .\n"));
  168.     /* generate .otag file path */
  169.     strcpy(pathStore, "FONTS:");
  170.     filePath = pathStore+6;
  171.     if (options[0])
  172.     strcpy(filePath, (char *) options[O_NAME]);
  173.     else
  174.     strcpy(filePath, "CGTimes.font");
  175.     s = strrchr(filePath, '.');
  176.     if ((s == 0) || (strcmp(s, ".font")))
  177.     endGame("ERROR: NAME not .font name\n");
  178.  
  179.     strcpy(s, OTSUFFIX);
  180.  
  181.     D((".otag file \"%s\"\n", filePath));
  182.     /* open .otag file */
  183.     OTFile = Open(filePath, MODE_OLDFILE);
  184.     if (!OTFile) {
  185.     if (!strchr(filePath, ':')) {
  186.         filePath = pathStore;
  187.         OTFile = Open(filePath, MODE_OLDFILE);
  188.     }
  189.     }
  190.  
  191.     if (!OTFile)
  192.     endGame("no font file \"%s\"\n", filePath);
  193.  
  194.     strcpy(s, ".font");
  195.     D((".font file \"%s\"\n", filePath));
  196.  
  197.     /* read and verify the .otag */
  198.     if (Read(OTFile, OTags, sizeof(struct TagItem)) != sizeof(struct TagItem))
  199.     endGame("OTFile read fail (8 bytes)\n");
  200.  
  201.     if (OTags[0].ti_Tag != OT_FileIdent)
  202.     endGame(".otag first tag $%lx, not $%lx\n", OTags[0].ti_Tag,
  203.         OT_FileIdent);
  204.  
  205.     Seek(OTFile, 0, OFFSET_END);
  206.     if (Seek(OTFile, 0, OFFSET_BEGINNING) != OTags[0].ti_Data)
  207.     endGame(".otag file size wrong\n");
  208.  
  209.     if (OTags[0].ti_Data > MAXFILESIZE)
  210.     endGame(".otag file size %ld larger than program maximum %ld\n",
  211.         OTags[0].ti_Data, MAXFILESIZE);
  212.  
  213.     /* this is a valid .otag file header, read it */
  214.     if (Read(OTFile, OTags, OTags[0].ti_Data) != OTags[0].ti_Data)
  215.     endGame(".otag read failure\n");
  216.  
  217.     /* patch indirect pointers */
  218.     for (i = 0; i < OTags[0].ti_Data/sizeof(struct TagItem); i++) {
  219.     if (OTags[i].ti_Tag == TAG_DONE)
  220.         break;
  221.     if (OTags[i].ti_Tag & OT_Indirect)
  222.         OTags[i].ti_Data += (ULONG) OTags;
  223.     }
  224.  
  225.     /* ensure the associated glyph library is open */
  226.     /* get the library name */
  227.     s = (char *) GetTagData(OT_Engine, 0, OTags);
  228.     if (!s)
  229.     endGame("no OT_Engine tag\n");
  230.  
  231.     if (strcmp(s, "bullet"))
  232.     endGame("OT_Engine not \"bullet\" but \"%s\"\n", s);
  233.  
  234.     BulletBase = OpenLibrary("bullet.library", 0);
  235.     if (!BulletBase)
  236.     endGame("OpenLibrary \"bullet.library\" failed\n");
  237.  
  238.     GlyphEngine = OpenEngine();
  239.  
  240.     if (!GlyphEngine)
  241.     endGame("OpenEngine failed\n");
  242.  
  243.     error = setInfo(GlyphEngine, OT_OTagPath, filePath, TAG_DONE);
  244.     if (error)
  245.     endGame("setInfo(OTagPath) error %ld\n", error);
  246.  
  247.     error = setInfo(GlyphEngine, OT_OTagList, OTags, TAG_DONE);
  248.     if (error)
  249.     endGame("setInfo(OTagList) error %ld\n", error);
  250.  
  251.     /* modify environment from .otag */
  252.     if (result = GetTagData(OT_DeviceDPI, 0, OTags))
  253.     UTags[U_DPI].ti_Data = result;
  254.     if (result = GetTagData(OT_DotSize, 0, OTags))
  255.     UTags[U_DOTP].ti_Data = result;
  256.  
  257.     /* modify environment from parameters */
  258.     if (options[O_DPIX] && options[O_DPIY])
  259.     UTags[U_DPI].ti_Data = (*options[O_DPIX]<<16) | *options[O_DPIY];
  260.     if (options[O_DOTPX] && options[O_DOTPY])
  261.     UTags[U_DOTP].ti_Data = (*options[O_DOTPX]<<16) | *options[O_DOTPY];
  262.  
  263.     if (error = SetInfoA(GlyphEngine, UTags))
  264.     endGame("setInfo(UTags) error %ld\n", error);
  265.  
  266.     Window = myOpenWindowTags(
  267.         WA_Left, 0,
  268.         WA_Top, 0,
  269.         WA_Width, X2,
  270.         WA_Height, Y2,
  271.         WA_IDCMP, CLOSEWINDOW,
  272.         WA_CloseGadget, TRUE,
  273.         WA_Title, "Sprial",
  274.         TAG_DONE);
  275.     
  276.     if (!Window)
  277.     endGame("OpenWindow failed\n");
  278.  
  279.     Template = AllocRaster(X2, Y2);
  280.     if (!Template)
  281.     endGame("AllocRaster failed\n");
  282.  
  283.     points = 1;
  284.     x = CX;
  285.     y = CY+1;
  286.     SetAPen(Window->RPort, 1);
  287.     SetDrMd(Window->RPort, JAM1);
  288.     for (charIndex = 0; charIndex < strlen(SpiralText); charIndex++, points++) {
  289.     /* point size tag */
  290.     pointVal = points << 16;
  291.     /* rotation tag */
  292.     h = sqrt((double) ((x-CX)*(x-CX) + (y-CY)*(y-CY)));
  293.     if (x>=CX) {
  294.         sinVal = ((double)(x-CX)/h*65526);
  295.     }
  296.     else {
  297.         sinVal = ((double)(CX-x)/h*65526);
  298.         sinVal = -sinVal;
  299.     }
  300.     if (y>=CY) {
  301.         cosVal = ((double)(y-CY)/h*65526);
  302.     }
  303.     else {
  304.         cosVal = ((double)(CY-y)/h*65526);
  305.         cosVal = -cosVal;
  306.     }
  307.     D(("char '%lc' point $%08lx sin $%08lx cos $%08lx\n",
  308.         SpiralText[charIndex], pointVal, sinVal, cosVal));
  309.     if (SpiralText[charIndex] != ' ') {
  310.         if (error = setInfo(GlyphEngine, OT_PointHeight, pointVal,
  311.             OT_GlyphCode, SpiralText[charIndex],
  312.             OT_RotateSin, sinVal, OT_RotateCos, cosVal, TAG_DONE))
  313.         endGame("setInfo() failed %ld\n", error);
  314.         if (error = obtainInfo(GlyphEngine, OT_GlyphMap, &glyph, TAG_DONE))
  315.         endGame("obtainInfo(Glyph) error %ld\n", error);
  316.         D(("glyph $%lx, width %ld, height %ld, bitmap $%lx\n",
  317.             glyph, glyph->glm_BMModulo, glyph->glm_BMRows,
  318.             glyph->glm_BitMap));
  319.         D(("    Black- Left %ld, Top %ld, Width %ld, Height %ld\n",
  320.             glyph->glm_BlackLeft, glyph->glm_BlackTop,
  321.             glyph->glm_BlackWidth, glyph->glm_BlackHeight));
  322.         D(("    xOrigin $%08lx, yOrigin $%08lx\n",
  323.             glyph->glm_XOrigin, glyph->glm_YOrigin));
  324.         D(("    width %ld.%04ld\n", glyph->glm_Width>>16,
  325.             ((glyph->glm_Width&0xffff)*10000)>>16));
  326.  
  327.         for (i = (glyph->glm_BMRows*glyph->glm_BMModulo/4)-1; i >= 0; i--) {
  328.         ((ULONG *) Template)[i] = ((ULONG *) glyph->glm_BitMap)[i];
  329.         }
  330.         dx = x - glyph->glm_X0 + glyph->glm_BlackLeft;
  331.         dy = y - glyph->glm_Y0 + glyph->glm_BlackTop;
  332.         BltTemplate(((char *) Template)+
  333.             (glyph->glm_BlackTop*glyph->glm_BMModulo)+
  334.             ((glyph->glm_BlackLeft/16)*2), glyph->glm_BlackLeft&0xf,
  335.             glyph->glm_BMModulo, Window->RPort, dx, dy,
  336.             glyph->glm_BlackWidth, glyph->glm_BlackHeight);
  337.         releaseInfo(GlyphEngine, OT_GlyphMap, glyph, TAG_DONE);
  338.         escapement = glyph->glm_Width*points;
  339.     }
  340.     else {
  341.         escapement = pointVal/2;
  342.     }
  343.     x += (1.3*((((double) escapement/65536.0)*((double)cosVal/65536.0)))+
  344.         0.5);
  345.     y -= (1.3*((((double) escapement/65536.0)*((double)sinVal/65536.0)))+
  346.         0.5);
  347.     D(("dx %ld dy %ld, new x %ld y %ld\n", dx, dy, x, y));
  348.     }
  349.  
  350.     D(("done w/ spiral.\n"));
  351.     D(("UserPort $%lx\n", Window->UserPort));
  352.     /* wait until done before returning */
  353.     for (;;) {
  354.     while (IM = (struct IntuiMessage *) GetMsg(Window->UserPort)) {
  355.         D(("IM Class $%08lx\n", IM->Class));
  356.         if (IM->Class & CLOSEWINDOW) {
  357.         D(("CLOSEWINDOW\n"));
  358.         endGame(0);
  359.         }
  360.         ReplyMsg((struct Message *) IM);
  361.     }
  362.     D(("WaitPort..."));
  363.     WaitPort(Window->UserPort);
  364.     D(("WAKE!\n"));
  365.     }
  366. }
  367.